<template>
  <div>
    <div class="page-sd">
      <div class="inner custom-scroll">
        <div class="sd-box">
          <h2>Stable Diffusion 创作中心</h2>

        <div class="sd-params" :style="{ height: mjBoxHeight + 'px' }">
          <div class="param-line" style="padding-top: 10px">
            <el-tabs class="my-tabs" v-model="channel" @tab-click="tabClick">
              <el-tab-pane label="本地SD" name="SD_LOCAL">
                <el-form :model="params" label-width="80px" label-position="left">
                  <div class="param-line" style="padding-top: 10px">
                    <el-form-item label="采样方法">
                      <template #default>
                        <div class="form-item-inner">
                          <el-select v-model="params.sampler" size="small">
                            <el-option v-for="item in samplers" :label="item" :value="item" :key="item"/>
                          </el-select>
                          <el-tooltip
                              effect="light"
                              content="出图效果比较好的一般是 Euler 和 DPM 系列算法"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>

                  <div class="param-line">
                    <el-form-item label="图片尺寸">
                      <template #default>
                        <div class="form-item-inner">
                          <el-row :gutter="20">
                            <el-col :span="12">
                              <el-input v-model.number="params.width" size="small" placeholder="图片宽度"/>
                            </el-col>
                            <el-col :span="12">
                              <el-input v-model.number="params.height" size="small" placeholder="图片高度"/>
                            </el-col>
                          </el-row>
                        </div>
                      </template>
                    </el-form-item>
                  </div>

                  <div class="param-line">
                    <el-form-item label="迭代步数">
                      <template #default>
                        <div class="form-item-inner">
                          <el-input v-model.number="params.steps" size="small"/>
                          <el-tooltip
                              effect="light"
                              content="值越大则代表细节越多，同时也意味着出图速度越慢"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>

                  <div class="param-line">
                    <el-form-item label="引导系数">
                      <template #default>
                        <div class="form-item-inner">
                          <el-input v-model.number="params.cfg_scale" size="small"/>
                          <el-tooltip
                              effect="light"
                              content="提示词引导系数，图像在多大程度上服从提示词<br/> 较低值会产生更有创意的结果"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>

                  <div class="param-line">
                    <el-form-item label="随机因子">
                      <template #default>
                        <div class="form-item-inner">
                          <el-input v-model.number="params.seed" size="small"/>
                          <el-tooltip
                              effect="light"
                              content="随机数种子，相同的种子会得到相同的结果<br/> 设置为 -1 则每次随机生成种子"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>

                          <el-tooltip
                              effect="light"
                              content="使用随机数"
                              raw-content
                              placement="right"
                          >
                            <el-icon @click="params.seed = -1">
                              <Orange/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>

                  <div class="param-line">
                    <el-form-item label="高清修复">
                      <template #default>
                        <div class="form-item-inner">
                          <el-switch v-model="params.enable_hr" style="--el-switch-on-color: #47fff1;"/>
                          <el-tooltip
                              effect="light"
                              content="先以较小的分辨率生成图像，接着方法图像<br />然后在不更改构图的情况下再修改细节"
                              raw-content
                              placement="right"
                          >
                            <el-icon style="margin-top: 6px">
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>

                  <div v-show="params.enable_hr">
                    <div class="param-line">
                      <el-form-item label="重绘幅度">
                        <template #default>
                          <div class="form-item-inner">
                            <el-slider v-model.number="params.denoising_strength" :max="1" :step="0.1"
                                       style="width: 180px;--el-slider-main-bg-color:#47fff1"/>
                            <el-tooltip
                                effect="light"
                                content="决定算法对图像内容的影响程度<br />较大的值将得到越有创意的图像"
                                raw-content
                                placement="right"
                            >
                              <el-icon style="margin-top: 6px">
                                <InfoFilled/>
                              </el-icon>
                            </el-tooltip>
                          </div>
                        </template>
                      </el-form-item>
                    </div>

                    <div class="param-line">
                      <el-form-item label="放大算法">
                        <template #default>
                          <div class="form-item-inner">
                            <el-select v-model="params.hr_upscaler" size="small">
                              <el-option v-for="item in scaleAlg" :label="item" :value="item" :key="item"/>
                            </el-select>
                            <el-tooltip
                                effect="light"
                                content="高清修复放大算法，主流算法有Latent和ESRGAN_4x"
                                raw-content
                                placement="right"
                            >
                              <el-icon>
                                <InfoFilled/>
                              </el-icon>
                            </el-tooltip>
                          </div>
                        </template>
                      </el-form-item>
                    </div>

                    <div class="param-line">
                      <el-form-item label="放大倍数">
                        <template #default>
                          <div class="form-item-inner">
                            <el-input v-model.number="params.hr_scale" size="small"/>
                            <el-tooltip
                                effect="light"
                                content="随机数种子，相同的种子会得到相同的结果<br/> 设置为 -1 则每次随机生成种子"
                                raw-content
                                placement="right"
                            >
                              <el-icon>
                                <InfoFilled/>
                              </el-icon>
                            </el-tooltip>
                          </div>
                        </template>
                      </el-form-item>
                    </div>

                    <div class="param-line">
                      <el-form-item label="迭代步数">
                        <template #default>
                          <div class="form-item-inner">
                            <el-input v-model.number="params.hr_second_pass_steps" size="small"/>
                            <el-tooltip
                                effect="light"
                                content="重绘迭代步数，如果设置为0，则设置跟原图相同的迭代步数"
                                raw-content
                                placement="right"
                            >
                              <el-icon>
                                <InfoFilled/>
                              </el-icon>
                            </el-tooltip>
                          </div>
                        </template>
                      </el-form-item>
                    </div>
                  </div>

                  <div class="param-line"  element-loading-background="rgba(122, 122, 122, 0.8)">
                    <el-input
                        v-model="params.prompt"
                        :autosize="{ minRows: 4, maxRows: 6 }"
                        type="textarea"
                        ref="promptRef"
                        placeholder="请在此输入绘画提示词，系统会自动翻译中文提示词，高手请直接输入英文提示词"
                    />
                  </div>
                  <div class="param-line pt">
                    <span>反向提示词：</span>
                    <el-tooltip
                        effect="light"
                        content="不希望出现的元素，下面给了默认的起手式"
                        placement="right"
                    >
                      <el-icon>
                        <InfoFilled/>
                      </el-icon>
                    </el-tooltip>
                  </div>
                  <div class="param-line">
                    <el-input
                        v-model="params.negative_prompt"
                        :autosize="{ minRows: 4, maxRows: 6 }"
                        type="textarea"
                        placeholder="反向提示词"
                    />
                  </div>

                  <div class="param-line" style="padding: 10px">
                    <el-tag type="success">绘图可用额度：{{ power }}</el-tag>
                  </div>
                </el-form>
              </el-tab-pane>
              <el-tab-pane label="云端SD(测试版本)" name="SD_STABILITY">
                <el-form :model="stabilityParams" label-width="80px" label-position="left">
                  <div class="param-line" style="padding-top: 10px">
                    <el-form-item label="采样方法">
                      <template #default>
                        <div class="form-item-inner">
                          <el-select v-model="stabilityParams.sampler" size="small">
                            <el-option v-for="item in stabilitySamplers" :label="item" :value="item" :key="item"/>
                          </el-select>
                          <el-tooltip
                              effect="light"
                              content="出图效果比较好的一般是 Euler 和 DPM 系列算法"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>
                  <div class="param-line" style="padding-top: 10px">
                    <el-form-item label="图片风格">
                      <template #default>
                        <div class="form-item-inner">
                          <el-select v-model="stabilityParams.style_preset" size="small">
                            <el-option v-for="item in stylePreset" :label="item" :value="item" :key="item"/>
                          </el-select>
                          <el-tooltip
                              effect="light"
                              content="传入样式预设以引导图像模型走向特定样式。此样式预设列表可能会发生变化。"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>
                  <div class="param-line" style="padding-top: 10px">
                    <el-form-item label="剪辑指导">
                      <template #default>
                        <div class="form-item-inner">
                          <el-select v-model="stabilityParams.clip_guidance_preset" size="small">
                            <el-option v-for="item in clipGuidancePreset" :label="item" :value="item" :key="item"/>
                          </el-select>
                          <el-tooltip
                              effect="light"
                              content="剪辑指导"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>
                  <div class="param-line">
                    <el-form-item label="图片尺寸">
                      <template #default>
                        <div class="form-item-inner">
                          <el-row :gutter="20">
                            <el-col :span="12">
                              <el-input v-model.number="stabilityParams.width" size="small" placeholder="图片宽度"/>
                            </el-col>
                            <el-col :span="12">
                              <el-input v-model.number="stabilityParams.height" size="small" placeholder="图片高度"/>
                            </el-col>
                          </el-row>
                        </div>
                      </template>
                    </el-form-item>
                  </div>

                  <div class="param-line">
                    <el-form-item label="迭代步数">
                      <template #default>
                        <div class="form-item-inner">
                          <el-input v-model.number="stabilityParams.steps" size="small"/>
                          <el-tooltip
                              effect="light"
                              content="值越大则代表细节越多，同时也意味着出图速度越慢"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>

                  <div class="param-line">
                    <el-form-item label="引导系数">
                      <template #default>
                        <div class="form-item-inner">
                          <el-input v-model.number="stabilityParams.cfg_scale" size="small"/>
                          <el-tooltip
                              effect="light"
                              content="提示词引导系数，图像在多大程度上服从提示词<br/> 较低值会产生更有创意的结果"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>

                  <div class="param-line">
                    <el-form-item label="随机因子">
                      <template #default>
                        <div class="form-item-inner">
                          <el-input v-model.number="stabilityParams.seed" size="small"/>
                          <el-tooltip
                              effect="light"
                              content="随机数种子，相同的种子会得到相同的结果<br/> 设置为 0 则每次随机生成种子"
                              raw-content
                              placement="right"
                          >
                            <el-icon>
                              <InfoFilled/>
                            </el-icon>
                          </el-tooltip>

                          <el-tooltip
                              effect="light"
                              content="使用随机数"
                              raw-content
                              placement="right"
                          >
                            <el-icon @click="stabilityParams.seed = 0">
                              <Orange/>
                            </el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </el-form-item>
                  </div>
                  <div class="param-line" element-loading-background="rgba(122, 122, 122, 0.8)">
                    <span>正向提示词：</span>
                    <el-tooltip
                        effect="light"
                        content="写出你希望画出的图画"
                        placement="right"
                    >
                      <el-icon>
                        <InfoFilled/>
                      </el-icon>
                    </el-tooltip>
                    <el-input
                        v-model="stabilityParams.prompt"
                        :autosize="{ minRows: 4, maxRows: 6 }"
                        type="textarea"
                        ref="promptRef"
                        placeholder="正向提示词，例如：A chinese girl walking in the middle of a cobblestone street"
                    />
                  </div>
                  <div class="param-line pt">
                    <span>反向提示词：</span>
                    <el-tooltip
                        effect="light"
                        content="不希望出现的元素，下面给了默认的起手式"
                        placement="right"
                    >
                      <el-icon>
                        <InfoFilled/>
                      </el-icon>
                    </el-tooltip>
                  </div>
                  <div class="param-line">
                    <el-input
                        v-model="stabilityParams.negative_prompt"
                        :autosize="{ minRows: 4, maxRows: 6 }"
                        type="textarea"
                        placeholder="反向提示词"
                    />
                  </div>
                  <div class="param-line" style="padding: 10px">
                    <el-tag type="success">绘图可用额度：{{ power }}</el-tag>
                  </div>
                </el-form>
              </el-tab-pane>
            </el-tabs>
          </div>

        </div>
        <div class="submit-btn">
          <el-button color="#47fff1" :dark="false" round @click="generate">立即生成</el-button>
        </div>
      </div>

      <div class="task-list-box">
        <div class="task-list-inner" :style="{ height: listBoxHeight + 'px' }">
          <div class="job-list-box">
            <h2>任务列表</h2>
            <div class="running-job-list">
              <ItemList :items="runningJobs" v-if="runningJobs.length > 0" :width="240">
                <template #default="scope">
                  <div class="job-item">
                    <div v-if="scope.item.progress > 0" class="job-item-inner">
                      <el-image :src="scope.item['img_url']"
                                fit="cover"
                                loading="lazy">
                        <template #placeholder>
                          <div class="image-slot">
<!--                            正在加载图片-->
                          </div>
                        </template>

                          <template #error>
                            <div class="image-slot">
                              <el-icon v-if="scope.item['img_url'] !== ''">
                                <Picture/>
                              </el-icon>
                            </div>
                          </template>
                        </el-image>

                      <div class="progress">
                        <el-progress type="circle" :percentage="scope.item.progress" :width="100" color="#47fff1"/>
                      </div>
                    </div>
                    <el-image fit="cover" v-else>
                      <template #error>
                        <div class="image-slot">
                          <i class="iconfont icon-quick-start"></i>
                          <span>任务正在排队中</span>
                        </div>
                      </template>
                    </el-image>
                  </div>
                </template>
              </ItemList>
              <el-empty :image-size="100" v-else/>
            </div>
            <h2>创作记录</h2>
            <div class="finish-job-list" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.7)">
              <ItemList :items="finishedJobs" v-if="finishedJobs.length > 0" :width="240" :gap="16">
                <template #default="scope">
                  <div class="job-item animate" @click="showTask(scope.item)">
                    <el-image
                        :src="scope.item['img_url']+'?imageView2/1/w/240/h/240/q/75'"
                        fit="cover"
                        loading="lazy">
                      <template #placeholder>
                        <div class="image-slot">
                          正在加载图片
                        </div>
                      </template>

                          <template #error>
                            <div class="image-slot">
                              <el-icon>
                                <Picture/>
                              </el-icon>
                            </div>
                          </template>
                        </el-image>

                    <div class="remove">
                      <el-button type="danger" :icon="Delete" @click="removeImage($event,scope.item)" circle/>
                      <el-button type="warning" v-if="scope.item.publish"
                                 @click="publishImage($event,scope.item, false)"
                                 circle>
                        <i class="iconfont icon-cancel-share"></i>
                      </el-button>
                      <el-button type="success" v-else @click="publishImage($event,scope.item, true)" circle>
                        <i class="iconfont icon-share-bold"></i>
                      </el-button>
                    </div>
                  </div>
                </template>
              </ItemList>
              <el-empty :image-size="100" v-else/>
            </div> <!-- end finish job list-->
            <div class="pagination">
              <el-pagination v-if="total > 0" background
                             layout="total,prev, pager, next"
                             :hide-on-single-page="true"
                             v-model:current-page="page"
                             v-model:page-size="pageSize"
                             @current-change="fetchFinishJobs()"
                             :total="total"/>

            </div>
          </div>
        </div>

        </div><!-- end task list box -->
      </div>

      <!-- 任务详情弹框 -->
      <el-dialog v-model="showTaskDialog" title="绘画任务详情" :fullscreen="true">
        <el-row :gutter="20">
          <el-col :span="16">
            <div class="img-container" :style="{maxHeight: fullImgHeight+'px'}">
              <el-image :src="item['img_url']" fit="contain"/>
            </div>
          </el-col>
          <el-col :span="8">
            <div class="task-info">
              <div class="info-line">
                <el-divider>
                  正向提示词
                </el-divider>
                <div class="prompt">
                  <span>{{ item.prompt }}</span>
                  <el-icon class="copy-prompt-sd" :data-clipboard-text="item.prompt">
                    <DocumentCopy/>
                  </el-icon>
                </div>

              </div>

              <div class="info-line">
                <el-divider>
                  反向提示词
                </el-divider>
                <div class="prompt">
                  <span>{{ item.params.negative_prompt }}</span>
                  <el-icon class="copy-prompt-sd" :data-clipboard-text="item.params.negative_prompt">
                    <DocumentCopy/>
                  </el-icon>
                </div>
              </div>

              <div class="info-line">
                <div class="wrapper">
                  <label>采样方法：</label>
                  <div class="item-value">{{ item.params.sampler }}</div>
                </div>
              </div>

              <div class="info-line">
                <div class="wrapper">
                  <label>图片尺寸：</label>
                  <div class="item-value">{{ item.params.width }} x {{ item.params.height }}</div>
                </div>
              </div>

              <div class="info-line">
                <div class="wrapper">
                  <label>迭代步数：</label>
                  <div class="item-value">{{ item.params.steps }}</div>
                </div>
              </div>

              <div class="info-line">
                <div class="wrapper">
                  <label>引导系数：</label>
                  <div class="item-value">{{ item.params.cfg_scale }}</div>
                </div>
              </div>

              <div class="info-line">
                <div class="wrapper">
                  <label>随机因子：</label>
                  <div class="item-value">{{ item.params.seed }}</div>
                </div>
              </div>

              <div v-if="item.params.hd_fix">
                <el-divider>
                  高清修复
                </el-divider>
                <div class="info-line">
                  <div class="wrapper">
                    <label>重绘幅度：</label>
                    <div class="item-value">{{ item.params.hd_redraw_rate }}</div>
                  </div>
                </div>

                <div class="info-line">
                  <div class="wrapper">
                    <label>放大算法：</label>
                    <div class="item-value">{{ item.params.hd_scale_alg }}</div>
                  </div>
                </div>

                <div class="info-line">
                  <div class="wrapper">
                    <label>放大倍数：</label>
                    <div class="item-value">{{ item.params.hd_scale }}</div>
                  </div>
                </div>

                <div class="info-line">
                  <div class="wrapper">
                    <label>迭代步数：</label>
                    <div class="item-value">{{ item.params.hd_steps }}</div>
                  </div>
                </div>
              </div>

              <div class="copy-params">
                <el-button type="primary" round @click="copyParams(item)">画一张同款的</el-button>
              </div>

            </div>
          </el-col>
        </el-row>

      </el-dialog>
    </div>

    <login-dialog :show="showLoginDialog" @hide="showLoginDialog =  false" @success="initData"/>
  </div>
</template>

<script setup>
import {onMounted, onUnmounted, ref} from "vue"
import {Delete, DocumentCopy, InfoFilled, Orange, Picture, Refresh} from "@element-plus/icons-vue";
import {httpGet, httpPost} from "@/utils/http";
import {ElMessage, ElMessageBox, ElNotification} from "element-plus";
import ItemList from "@/components/ItemList.vue";
import Clipboard from "clipboard";
import {checkSession} from "@/action/session";
import {useRouter} from "vue-router";
import {getSessionId} from "@/store/session";
import LoginDialog from "@/components/LoginDialog.vue";

const listBoxHeight = ref(window.innerHeight - 40)
const mjBoxHeight = ref(window.innerHeight - 150)
const fullImgHeight = ref(window.innerHeight - 60)
const showTaskDialog = ref(false)
const item = ref({})
const showLoginDialog = ref(false)
const isLogin = ref(false)

window.onresize = () => {
  listBoxHeight.value = window.innerHeight - 40
  mjBoxHeight.value = window.innerHeight - 150
}
let samplers = ["Euler a", "DPM++ 2S a Karras", "DPM++ 2M Karras", "DPM++ SDE Karras", "DPM++ 2M SDE Karras"]
const stabilitySamplers = ["DDIM", "DDPM", "K_DPMPP_2M", "K_DPMPP_2S_ANCESTRAL", "K_DPMPP_SDE", "K_DPM_2", "K_DPM_2_ANCESTRAL", "K_EULER", "K_EULER_ANCESTRAL", "K_HEUN", "K_LMS"]
const scaleAlg = ["Latent", "ESRGAN_4x", "R-ESRGAN 4x+", "SwinIR_4x", "LDSR"]
const stylePreset = ["3d-model", "analog-film", "anime", "cinematic", "comic-book", "digital-art", "enhance", "fantasy-art", "isometric", "line-art", "low-poly", "modeling-compound", "neon-punk", "origami", "photographic", "pixel-art", "tile-texture"];
const clipGuidancePreset = ["NONE", "FAST_BLUE", "FAST_GREEN", "NONE", "SIMPLE", "SLOW", "SLOWER", "SLOWEST"];
let channel = "SD_LOCAL"
const params = ref({
  width: 1024,
  height: 1024,
  sampler: samplers[0],
  seed: -1,
  steps: 20,
  cfg_scale: 7,
  style_preset: false,
  enable_hr: false,
  denoising_strength: 0.7,
  hr_scale: 2,
  hr_upscaler: scaleAlg[0],
  hr_second_pass_steps: 15,
  channel: "SD_LOCAL",
  prompt: "",
  negative_prompt: "nsfw, paintings,low quality,easynegative,ng_deepnegative ,lowres,bad anatomy,bad hands,bad feet",
})

const stabilityParams = ref({
  width: 512,
  height: 512,
  sampler: stabilitySamplers[0],
  seed: 0,
  steps: 30,
  cfg_scale: 7,
  style_preset: stylePreset[0],
  clip_guidance_preset: clipGuidancePreset[0],
  channel: "SD_STABILITY",
  prompt: "",
  negative_prompt: "nsfw, paintings,low quality,easynegative,ng_deepnegative ,lowres,bad anatomy,bad hands,bad feet",
})
const tabClick = (tab) => {
  channel = tab.props.name
}

const runningJobs = ref([])
const finishedJobs = ref([])
const router = useRouter()
// 检查是否有画同款的参数
const _params = router.currentRoute.value.params["copyParams"]
if (_params) {
  params.value = JSON.parse(_params)
}
const power = ref(0)
const sdPower = ref(0) // 画一张 SD 图片消耗算力

const socket = ref(null)
const userId = ref(0)
const heartbeatHandle = ref(null)
const connect = () => {
  let host = process.env.VUE_APP_WS_HOST
  if (host === '') {
    if (location.protocol === 'https:') {
      host = 'wss://' + location.host;
    } else {
      host = 'ws://' + location.host;
    }
  }

  // 心跳函数
  const sendHeartbeat = () => {
    clearTimeout(heartbeatHandle.value)
    new Promise((resolve, reject) => {
      if (socket.value !== null) {
        socket.value.send(JSON.stringify({type: "heartbeat", content: "ping"}))
      }
      resolve("success")
    }).then(() => {
      heartbeatHandle.value = setTimeout(() => sendHeartbeat(), 5000)
    });
  }

  const _socket = new WebSocket(host + `/api/sd/client?user_id=${userId.value}`);
  _socket.addEventListener('open', () => {
    socket.value = _socket;

    // 发送心跳消息
    sendHeartbeat()
  });

  _socket.addEventListener('message', event => {
    if (event.data instanceof Blob) {
      const reader = new FileReader();
      reader.readAsText(event.data, "UTF-8");
      reader.onload = () => {
        const data = reader.result;
        if (data === "running") {
          fetchRunningJobs()
        } else if (data === "finish") {
          fetchRunningJobs()
          fetchFinishJobs(1)
        }
      }
    }
  });

  _socket.addEventListener('close', () => {
    if (socket.value !== null) {
      connect()
    }
  });
}

const clipboard = ref(null)
onMounted(() => {
  initData()
  clipboard.value = new Clipboard('.copy-prompt-sd');
  clipboard.value.on('success', () => {
    ElMessage.success("复制成功！");
  })

  clipboard.value.on('error', () => {
    ElMessage.error('复制失败！');
  })

  httpGet("/api/config/get?key=system").then(res => {
    sdPower.value = res.data["sd_power"]
  }).catch(e => {
    ElMessage.error("获取系统配置失败：" + e.message)
  })
})

onUnmounted(() => {
  clipboard.value.destroy()
  socket.value = null
})


const initData = () => {
  checkSession().then(user => {
    power.value = user['power']
    userId.value = user.id
    isLogin.value = true
    fetchRunningJobs()
    fetchFinishJobs(1)
    connect()
  }).catch(() => {
    loading.value = false
  });
}

const fetchRunningJobs = () => {
  // 获取运行中的任务
  httpGet(`/api/sd/runningJobs`).then(res => {
    const jobs = res.data
    const _jobs = []
    for (let i = 0; i < jobs.length; i++) {
      if (jobs[i].progress === -1) {
        ElNotification({
          title: '任务执行失败',
          dangerouslyUseHTMLString: true,
          message: `任务ID：${jobs[i]['task_id']}<br />原因：${jobs[i]['err_msg']}`,
          type: 'error',
        })
        power.value += sdPower.value
        continue
      }
      _jobs.push(jobs[i])
    }
    runningJobs.value = _jobs
  }).catch(e => {
    ElMessage.error("获取任务失败：" + e.message)
  })
}

// const handleScrollEnd = () => {
//   page.value += 1
//   fetchFinishJobs(page.value)
// }

const page = ref(1)
const pageSize = ref(15)
const total = ref(0)
const loading = ref(false)
// 获取已完成的任务
const fetchFinishJobs = () => {

  loading.value = true
  // 获取已完成的任务
  httpGet(`/api/sd/finishJobs?page=${page.value}&page_size=${pageSize.value}`).then(res => {
    const jobs = res.data.items
    for (let i = 0; i < jobs.length; i++) {
      if (jobs[i]['use_proxy']) {
        jobs[i]['thumb_url'] = jobs[i]['img_url'] + '?x-oss-process=image/quality,q_60&format=webp'
      } else {
        if (jobs[i].type === 'upscale' || jobs[i].type === 'swapFace') {
          jobs[i]['thumb_url'] = jobs[i]['img_url'] + '?imageView2/1/w/480/h/600/q/75'
        } else {
          jobs[i]['thumb_url'] = jobs[i]['img_url'] + '?imageView2/1/w/480/h/480/q/75'
        }
      }
    }
    finishedJobs.value = jobs
    total.value = res.data.total
    page.value = res.data.page
    pageSize.value = res.data.page_size
    loading.value = false
  }).catch(e => {
    loading.value = false
    ElMessage.error("获取任务失败：" + e.message)
  })
}


// 创建绘图任务
const promptRef = ref(null)
const generate = () => {
  console.log(isLogin.value)
  if (!isLogin.value) {
    showLoginDialog.value = true
    return;
  }
  if (power.value < sdPower.value){
    return ElMessage.error("算力不足，请充值后再试！")
  }
  if (channel === "SD_LOCAL") {
    if (params.value.prompt === '') {
      promptRef.value.focus()
      return ElMessage.error("请输入绘画提示词！")
    }
    if (params.value.seed === '') {
      params.value.seed = -1
    }
    params.value.session_id = getSessionId()
    httpPost("/api/sd/image", params.value).then(() => {
      ElMessage.success("绘画任务推送成功，请耐心等待任务执行...")
      power.value -= sdPower.value
    }).catch(e => {
      ElMessage.error("任务推送失败：" + e.message)
    })
  } else {
    if (stabilityParams.value.prompt === '') {
      promptRef.value.focus()
      return ElMessage.error("请输入绘画提示词！")
    }
    params.value.session_id = getSessionId()
    httpPost("/api/sd/imageForStability", stabilityParams.value).then(() => {
      ElMessage.success("绘画任务推送成功，请耐心等待任务执行...")
      power.value -= sdPower.value
    }).catch(e => {
      ElMessage.error("任务推送失败：" + e.message)
    })
  }

}

const showTask = (row) => {
  item.value = row
  showTaskDialog.value = true
}

const copyParams = (row) => {

  params.value = row.params
  console.log("来咯来咯",row.params)
  showTaskDialog.value = false
  channel = row.channel
}

const removeImage = (event, item) => {
  event.stopPropagation()
  ElMessageBox.confirm(
      '此操作将会删除任务和图片，继续操作码?',
      '删除提示',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
  ).then(() => {
    httpPost("/api/sd/remove", {id: item.id, img_url: item.img_url, user_id: userId.value}).then(() => {
      ElMessage.success("任务删除成功")
      initData();
    }).catch(e => {
      ElMessage.error("任务删除失败：" + e.message)
    })
  }).catch(() => {
  })
}

// 发布图片到作品墙
const publishImage = (event, item, action) => {
  event.stopPropagation()
  let text = "图片发布"
  if (action === false) {
    text = "取消发布"
  }
  httpPost("/api/sd/publish", {id: item.id, action: action}).then(() => {
    ElMessage.success(text + "成功")
    item.publish = action
  }).catch(e => {
    ElMessage.error(text + "失败：" + e.message)
  })
}

</script>

<style lang="stylus">
@import "@/assets/css/image-sd.styl"
@import "@/assets/css/custom-scroll.styl"

.pagination {
  margin: 20px 0 0 0;
  display: flex;
  justify-content: center;
  width: 100%;
}

.my-tabs .el-tabs__item {
  color: white;
}
</style>
